package com.yjzx.util.common.util.batch.merging;

/**
 * @author yjzx
 * @date 2024/6/18
 * @description ReportOverview
 */

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;

/**
 * @param <T> 参数类型
 * @param <U> 节点类型
 * @param <R> 返回值类型
 * @author yjzx
 * @date 2024/06/18
 * @description ReportOverview
 */
public class OverviewMerging<T, U extends Comparable<U>, R> extends DataMerging<T, U, R> {
    /**
     * 需要判断大小的起始获取
     */
    private Function<T, U> uStartGet;
    /**
     * 需要判断大小的起始修改
     */
    private BiConsumer<T, U> uStartSet;
    /**
     * 需要判断大小的结束获取
     */
    private Function<T, U> uEndGet;
    /**
     * 需要判断大小的结束修改
     */
    private BiConsumer<T, U> uEndSet;

    /**
     * 分段式方法
     *
     * @param uStartGet 开始时间获取
     * @param uStartSet 开始时间修改
     * @param uEndGet   结束时间获取
     * @param uEndSet   结束时间修改
     * @return
     */
    protected OverviewMerging(DataMerging<T, U, R> data, Function<T, U> uStartGet, BiConsumer<T, U> uStartSet, Function<T, U> uEndGet, BiConsumer<T, U> uEndSet) {
        super(data);
        this.uStartGet = uStartGet;
        this.uStartSet = uStartSet;
        this.uEndGet = uEndGet;
        this.uEndSet = uEndSet;
        check();
    }

    public List<R> toDataMerging() {
        check();
        //时间节点
        U dataStart = this.uStartGet.apply(param);
        U dataEnd = this.uEndGet.apply(param);
        U u = this.u;
        U uPreceding = this.uPreceding;
        List<R> result = new ArrayList<>();
        if (u.compareTo(dataEnd) > 0) {
            result.add(this.oldReportParam.apply(param));
        } else if (u.compareTo(dataStart) <= 0) {
            result.add(this.newReportParam.apply(param));
        } else {
            this.uEndSet.accept(param, uPreceding);
            result.add(this.oldReportParam.apply(param));

            this.uStartSet.accept(param, u);
            this.uEndSet.accept(param, dataEnd);
            result.add(this.newReportParam.apply(param));
        }
        return result;
    }

}
